package com.gin.kotlin.vegetables_kot.base

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.drawable.Drawable
import android.util.Log
import android.util.TypedValue
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.annotation.AttrRes
import androidx.annotation.ColorInt
import androidx.annotation.DrawableRes
import androidx.appcompat.content.res.AppCompatResources
import androidx.recyclerview.widget.RecyclerView
import androidx.viewbinding.ViewBinding
import com.gin.kotlin.vegetables_kot.R

import com.gin.kotlin.vegetables_kot.base.AbstractBindingActivity

/**
 * 抽象适配器
 * @param T : ViewBinding
 * @param D 数据类型
 * @property context Context
 * @property handler MyHandler
 * @property zebraStripe Boolean
 * @property data MutableList<D>
 * @constructor
 */
abstract class AbstractBindingRecyclerViewAdapter<T : ViewBinding, D>(
    protected val context: Context,
    protected val handler: MyHandler,
    /**
     * 是否使用斑马纹配色
     */
    private var zebraStripe: Boolean = true,
    /**
     * 数据
     */
    var data: MutableList<D> = mutableListOf(),
) : RecyclerView.Adapter<AbstractBindingRecyclerViewAdapter.ViewHolder<T>>(), ViewBindProvider<T> {
    protected val TAG = this::class.java.simpleName


    constructor(context: Context, handler: MyHandler) : this(context, handler, true)

    /**
     * 构造 ViewHolder
     * @param parent ViewGroup
     * @param viewType Int
     * @return ViewHolder<T>
     */
    final override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder<T> {
        val inflater = LayoutInflater.from(parent.context)
        val binding = instanceViewBinding(inflater, parent)!!
        // **根布局的宽高设置会丢失，需要重新配置**
        binding.root.layoutParams = configLayoutParams(ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT))
        return ViewHolder(binding)
    }

    /**
     * 配置 LayoutParams
     * @param layoutParams LayoutParams
     */
    open fun configLayoutParams(layoutParams: ViewGroup.LayoutParams): ViewGroup.LayoutParams {
        return layoutParams
    }

    /**
     * 实例化 ViewBinding 对象, 使用对应模板的Binding类的inflate方法进行构造
     * @param inflater 渲染器
     * @param container 容器(Fragment用)
     * @return T
     */
    override fun instanceViewBinding(inflater: LayoutInflater, container: ViewGroup?): T? {
        val parameterizedType =
            AbstractBindingActivity.findParameterizedType(this.javaClass) ?: throw RuntimeException("ViewBinding创建失败: ${this.javaClass.simpleName}, 泛型未找到")
        for (type in parameterizedType.actualTypeArguments) {
            if (type is Class<*>) {
                try {
                    val method = type.getMethod("inflate", LayoutInflater::class.java, ViewGroup::class.java, Boolean::class.javaPrimitiveType)
                    @Suppress("UNCHECKED_CAST") return method.invoke(type, inflater, container, false) as T
                } catch (e: NoSuchMethodException) {
                    Log.d(TAG, "instanceViewBinding: 方法未找到")
                }
            }
        }
        return null
    }

    /**
     * 根据drawable Id 获取 Drawable
     */
    fun getDrawable(@DrawableRes drawableId: Int): Drawable? {
        return AppCompatResources.getDrawable(context, drawableId)
    }

    /**
     * 根据AttrId获取 colorID
     */
    @ColorInt
    fun getAttrColor(@AttrRes attrId: Int): Int {
        val typedValue = TypedValue()
        context.theme.resolveAttribute(attrId, typedValue, true)
        return typedValue.data
    }

    /**
     * 当显示某一位置的item时的操作
     * @param holder ViewHolder<T>
     * @param position Int
     */
    final override fun onBindViewHolder(holder: ViewHolder<T>, position: Int) {
        // 如果使用斑马纹配色，修改背景色

        if (zebraStripe) {
            val color = if (position % 2 == 0) R.color.green_light else R.color.green_dark
            holder.b.root.setBackgroundColor(context.resources.getColor(color,context.theme))
        }

        onBindViewHolder(holder, position, holder.b, data[position])

    }

    final override fun getItemCount() = data.size

    /**
     * 当显示某一位置的item时的操作
     * @param holder ViewHolder
     * @param position Int
     * @param b ViewBinding
     * @param dataModel 数据对象
     */
    abstract fun onBindViewHolder(holder: ViewHolder<T>, position: Int, b: T, dataModel: D)

    /**
     * 替换数据
     * @param data MutableList<D>
     */
    @SuppressLint("NotifyDataSetChanged")
    fun replaceData(data: List<D>?) {
        handler.post {
            this.data = data?.toMutableList() ?: mutableListOf()
            notifyDataSetChanged()
        }
    }

    /**
     * 替换一个位置的数据
     * @param index Int
     * @param data D
     */
    fun replaceData(index:Int,data:D){
        handler.post {
            this.data[index] = data
            notifyItemChanged(index)
        }
    }

    /**
     * 追加数据
     * @param data List<D>
     */
    fun pushData(data: List<D>?, index: Int = this.data.size) {
        data?.size?.also {
            handler.post {
                this.data.addAll(index, data)
                notifyItemRangeInserted(index, it)
            }
        }
    }

    /**
     * 追加数据
     * @param data D
     * @param index Int
     */
    fun pushData(data: D, index: Int = this.data.size) = pushData(listOf(data), index)

    fun removeData(index: Int) {
        if (data.size > index) {
            handler.post {
                data.removeAt(index)
                notifyItemRemoved(index)
            }
        }
    }

    /**
     * 清空数据
     */
    fun clear() {
        val size = data.size
        handler.post {
            this.data.clear()
            notifyItemRangeRemoved(0, size)
        }
    }


    class ViewHolder<T : ViewBinding>(val b: T) : RecyclerView.ViewHolder(b.root)

}